#include "view/main_window.h"

#include <QMessageBox>
//#include <QPushBotton>
#include <QtGui>
#include <iostream>
#include <yaml-cpp/yaml.h>
#include <ros/package.h>
#include <QLineEdit>

#include "utils/utils_time.h"
#include "QTime"


namespace camera_calibration {

using namespace Qt;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindowDesign), edit_canera_(new EditCameraParamenters),
      edit_calibration_(new EditCalibrationParameters), usb_cam_command_(new QProcess(this)),
      calibration_command_(new QProcess(this)), tar_command_(new QProcess(this)),
      one_click_install_command_(new QProcess()), user_password_("") {
  ui->setupUi(this);
  this->setWindowIcon(QIcon(":/images/map_nav.jpg"));
  ui->password_edit->setEchoMode(QLineEdit::Password);
  ui->generate_file_push_button->setEnabled(false);
  ui->stackedWidget->setCurrentIndex(0);
  SignalSlotConnection();
  KillAllprocess();
}

MainWindow::~MainWindow() {
  delete ui;

  if (edit_canera_ != nullptr) {
    delete edit_canera_;
  }
  if (edit_calibration_ != nullptr) {
    delete edit_calibration_;
  }
  if (usb_cam_command_ != nullptr) {
    delete usb_cam_command_;
  }
  if (calibration_command_ != nullptr) {
    delete calibration_command_;
  }
  if (tar_command_ != nullptr) {
    delete tar_command_;
  }
  if (one_click_install_command_ != nullptr) {
    delete one_click_install_command_;
  }
}


void MainWindow::SignalSlotConnection() {
  connect(ui->password_edit, SIGNAL(textChanged(const QString &)), this, SLOT(SlotRecodePassword(const QString &)));
  connect(ui->start_push_button_1, SIGNAL(clicked()), this, SLOT(SlotStartCamera()));
  connect(ui->default_push_button_1, SIGNAL(clicked()), this, SLOT(SlotSetCameraDefaultParamenters()));
  connect(ui->start_push_button_2, SIGNAL(clicked()), this, SLOT(SlotSetRunparameters()));
  connect(ui->default_push_button_2, SIGNAL(clicked()), this, SLOT(SlotSetGridDefaultParamenters()));
  connect(ui->generate_file_push_button, SIGNAL(clicked()), this, SLOT(SlotGenerateFile()));
  connect(ui->go_back_button, SIGNAL(clicked()), this, SLOT(SlotGoBack()));
  connect(ui->close_apps_button,SIGNAL(clicked()),this,SLOT(SlotCloseApps()));
  connect(ui->one_click_install_button, SIGNAL(clicked()), this, SLOT(SlotOneClickInstall()));
}

void MainWindow::SlotStartCamera() {
  int image_width = ui->image_width_box->value();
  int image_height = ui->image_height_box->value();
  int device_id = ui->device_box->value();
  int edit_status = 0;

  if (user_password_ == "") {
    QMessageBox::StandardButton reply = QMessageBox::warning(
        this, tr("Warning"), "请先输入密码");
    if (reply == QMessageBox::Ok) {
      return;
    }
  }

  QProcess device_process;
  QString device_command = QString("echo '%1'|sudo -S chmod 777 /dev/video%2").arg(user_password_).arg(device_id);
  device_process.start("bash",QStringList() << "-c" << device_command);
  device_process.waitForFinished();
  if (device_process.exitCode() != 0) {
    QString err_str = device_process.readAllStandardError();
    QMessageBox::StandardButton reply = QMessageBox::warning(
        this, tr("Warning"), QString("运行失败！终端提示：%1").arg(err_str));
    if (reply == QMessageBox::Ok) {
      return;
    }
  }
  device_process.close();

  edit_canera_->EditStartupFile(image_width, image_height, device_id, edit_status);

  QProcess file_permission;
  QString permission_command = QString("echo '%1' | sudo -S cp -f %2 %3")
      .arg(user_password_)
      .arg("/tmp/usb_cam_modified.launch")
      .arg("/opt/ros/noetic/share/usb_cam/launch/usb_cam-test.launch");
  file_permission.start("bash",QStringList() << "-c" << permission_command);
  file_permission.waitForFinished(1000);

  usb_cam_command_->start("roslaunch", QStringList() << "usb_cam" << "usb_cam-test.launch");

  if (usb_cam_command_->exitCode() == 0) {
    ui->stackedWidget->setCurrentIndex(1);
  } else {
    QString err_str = usb_cam_command_->readAllStandardError();
    QMessageBox::StandardButton reply = QMessageBox::warning(
        this, tr("Warning"), QString("相机启动失败!终端提示：%1").arg(err_str));
    if (reply == QMessageBox::Ok) {
      return;
    }
  }
}

void MainWindow::SlotSetCameraDefaultParamenters() {
  int image_width = 0;
  int image_height = 0;
  int device_id = 0;
  edit_canera_->ReadCameraDefaultParameters(image_width, image_height, device_id);
  ui->image_width_box->setValue(image_width);
  ui->image_height_box->setValue(image_height);
  ui->device_box->setValue(device_id);
}

void MainWindow::SlotSetRunparameters() {
  int grid_x = ui->grid_x_box->value();
  int grid_y = ui->grid_y_box->value();
  double grid_width = ui->grid_width_box->value();

  QStringList run_command;
  run_command << "camera_calibration" << "cameracalibrator.py"
            << "--size" << QString("%1x%2").arg(grid_x).arg(grid_y)
            << "--square" << QString::number(grid_width, 'f', 3)
            << "image:=/usb_cam/image_raw"
            << "camera:=/usb_cam";

  calibration_command_->start("rosrun", run_command);
  if (calibration_command_->exitCode() != 0) {
    QString err_str = calibration_command_->readAllStandardError();
    QMessageBox::StandardButton reply = QMessageBox::warning(
          this,tr("Warning"),QString("运行失败！终端提示：%1").arg(err_str));
    if (reply == QMessageBox::Ok) {
      return;
    }
  }
}

void MainWindow::SlotSetGridDefaultParamenters() {
  int grid_x = 0;
  int grid_y = 0;
  double grid_width = 0;
  edit_calibration_->ReadGridDefaultParameters(grid_x , grid_y ,grid_width);
  ui->grid_x_box->setValue(grid_x);
  ui->grid_y_box->setValue(grid_y);
  ui->grid_width_box->setValue(grid_width);
}

void MainWindow::SlotGenerateFile() {

  std::cout<<"pose 1"<<std::endl;
  QString home_dir = QDir::homePath();
  QString calibration_data_dir = "/tmp/calibrationdata";
  QString extract_dir = home_dir + "/calibrationdata";

  QDir dir;
  if (!dir.exists(extract_dir)) {
    dir.mkpath(extract_dir);
  }

  tar_command_->start("tar", QStringList() << "-zxvf"
              << calibration_data_dir + ".tar.gz"
              <<"-C" << extract_dir );
  tar_command_->waitForFinished();
  if (tar_command_->exitCode() != 0) {
    QMessageBox::warning(this, tr("Error"),
                         QString("解压失败: %1").arg(QString(tar_command_->readAllStandardError())));
    return;
  }
  tar_command_->close();

  QString store_dir = extract_dir + "/ost.yaml";
  edit_calibration_->EditOstFile(store_dir);
  ui->file_store_line->setText(store_dir);
  ui->generate_file_push_button->setText("成功生成标定文件，请在对应目录查找！");
  ui->generate_file_push_button->setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(0, 255, 0);");
  ui->generate_file_push_button->setEnabled(false);


  KillAllprocess();
}

void MainWindow::SlotGoBack() {
  KillAllprocess();

  ui->file_store_line->setText("");
  ui->generate_file_push_button->setStyleSheet("");
  ui->generate_file_push_button->setText("点击生成标定文件");
  ui->generate_file_push_button->setEnabled(false);
  ui->close_apps_button->setEnabled(true);

  ui->stackedWidget->setCurrentIndex(0);
}

void MainWindow::SlotCloseApps() {
  KillAllprocess();

  ui->close_apps_button->setEnabled(false);
  ui->generate_file_push_button->setEnabled(true);
}

void MainWindow::SlotRecodePassword(const QString & _text) {
  user_password_= _text;
}

void MainWindow::SlotOneClickInstall() {

  if (user_password_ == "") {
    QMessageBox::StandardButton reply = QMessageBox::warning(
        this, tr("Warning"), "请先输入密码");
    if (reply == QMessageBox::Ok) {
      return;
    }
  }

  QString command = QString("echo '%1'|sudo -S apt-get install ros-noetic-usb-cam").arg(user_password_);
  one_click_install_command_->start("bash",QStringList() << "-c" << command);

  if (one_click_install_command_->exitCode() == 0){
    ui->one_click_install_button->setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(0, 255, 0);");
    ui->one_click_install_button->setText("一键安装成功！请启动相机！");
    ui->one_click_install_button->setEnabled(false);
  } else {
    QString err_str = one_click_install_command_->readAllStandardError();
    QMessageBox::StandardButton reply = QMessageBox::warning(
        this, tr("Warning"), QString("一键安装失败！请查看终端提示：%1").arg(err_str));
    if (reply == QMessageBox::Ok) {
      return;
    }
  }

}

void MainWindow::KillAllprocess() {
  if (usb_cam_command_->state() == QProcess::Running) {
    usb_cam_command_->kill();
    usb_cam_command_->waitForFinished(500);
  }

  QProcess killProcess;
  killProcess.start("pkill", QStringList() << "-f" << "usb_cam");
  killProcess.waitForFinished(1000);

  if (calibration_command_->state() == QProcess::Running) {
    calibration_command_->kill();
    calibration_command_->waitForFinished(500);
  }
}
}  // namespace camera_calibration
